function PictureUploader(params)
{
	//Parameters el = element
	var deleteButtonEl = params.deleteButton;
	var previewerEl = params.previewerEl;
	var setImageButtonEl = params.setImageButtonEl;
	var thumbsContainerEl = params.thumbsContainerEl;
	var setImageFx = params.setImageFx;
	var deleteImageFx = params.deleteImageFx;
	var uploadImageFx = params.uploadImageFx;
	var theImages = params.theImages; //Images to show in the thumbnailConainer these images must contain URL, PK , CSS class and Selected indicating if the image is the selected one or not (optional)
	var addButtonEl = params.addButtonEl;
	var numberImagesToShow = params.numberImagesToShow;
	var nextBttnEl = params.nextBttnEl;
	var backBttnEl = params.backBttnEl;
	var imageValidator = params.imageValidatorFx;
	var afterNext = params.afterNextFx;
	var afterBack = params.afterBackFx;
	var afterThumbClick = params.afterThumbClickFx;
	var noPictureEl = params.noPictureEl;
	var selectedThumbClass = params.selectedThumbClass;

	var theUploader = this;
	var theForm = createElement("form method=\"post\" enctype=\"multipart/form-data\" id=\"listingForm\" action=\"processImages.php\" style=\"display: none;\"");
	previewerEl.append(theForm);
	theUploader.imagesArray = [];
	theUploader.imageInPreviewer;
	theUploader.imageSet;

	this.getImageInPreviewer = function()
	{
		debugger;
		if(!theUploader.imageInPreviewer)
		{
			return null;
		}
		return {
				pk: theUploader.imageInPreviewer.imagePk,
				imageEl: $("#theImageInPreviewer"),
				imageUrl: theUploader.imageInPreviewer.imageUrl,
				rawObj: theUploader.imageInPreviewer.rawObj,
				selected: theUploader.imageInPreviewer.selected
				};
	}

	this.fireSet = function()
	{
		markImageAsSelected();
	}

	this.uploadedPictureCount = function()
	{
		return theUploader.imagesArray.length;
	}
	function createElement(element)
	{
		var elStr = "<"+element+"></"+element+">";
		return $(elStr);
	}
	function attachThumbSelectedClass(imageEl)
	{
		if(selectedThumbClass)
			{
				for(var i=0; i < theUploader.imagesArray.length; i++)
				{
					theUploader.imagesArray[i].imageEl.removeClass(selectedThumbClass);
				}
				imageEl.addClass(selectedThumbClass);
			}
	}
	function Image(url, pk, cssClass, rawObj){
		this.imageEl = createElement("div");//Div
		this.imageEl.addClass(cssClass);
		this.imageEl.css("background-image", "url('"+url+"')");
		this.imagePk = pk;
		this.imageUrl = url;
		this.rawObj = rawObj;
		var thisObj = this;

		this.imageEl.on("click", function(){
			putImageInPreviewer(thisObj);
			afterThumbClick();
		});

		this.removeImage = function()
		{
			$(this.imageEl).remove();
			theUploader.imagesArray.splice(theUploader.imagesArray.indexOf(this), 1);
		}
	}
	this.disableButtonsWhenNoPictures = disableButtonsWhenNoPictures;
	this.enableButtonsWhenNoPictures = enableButtonsWhenNoPictures;
	function disableButtonsWhenNoPictures(el)
	{
		debugger;
		$(el).css("opacity", "0.4").css("cursor", "default");

		$(el).off("click");
	}
	function enableButtonsWhenNoPictures(el, fx)
	{
		$(el).css("opacity", "1").css("cursor", "pointer");

		$(el).off("click");

		$(el).on("click", fx);
	}
	function putImageInPreviewer(imageCreated)
	{
		emptyPreviewer();
		theUploader.imageInPreviewer = imageCreated;
		var divImgageEl = createElement("div");
		var imageEl = createElement("img");
		$(imageEl).attr("id","theImageInPreviewer");
		var url = imageCreated.imageUrl;
		$(imageEl).attr("src", url);		
		divImgageEl.append(imageEl);
		previewerEl.append(divImgageEl);
		attachThumbSelectedClass(imageCreated.imageEl);
		//previewerEl.css("background-image", url);
	}
	function emptyPreviewer()
	{
		previewerEl.empty();
		theUploader.imageInPreviewer = null;
	}
	function putNoPicElInPreviewer(noPictureEl)
	{
		previewerEl.append(noPictureEl);
	}
	function afterDeleteImage(imgCreated){
		var currentDisplayedIndex = parseInt(theUploader.imagesArray.indexOf(theUploader.imageInPreviewer));
		var thereIsNext = theUploader.imagesArray.length > currentDisplayedIndex + 1;
		var thereIsBack = currentDisplayedIndex - 1 >= 0;
		imgCreated.removeImage();
		theForm.empty();
		debugger;
		if(thereIsNext) //There is nextImage
		{
			putImageInPreviewer(theUploader.imagesArray[currentDisplayedIndex]);
			enableButtonsWhenNoPictures(deleteButtonEl, deleteImage);
		}else if(thereIsBack){
			putImageInPreviewer(theUploader.imagesArray[currentDisplayedIndex - 1]);
			enableButtonsWhenNoPictures(deleteButtonEl, deleteImage);
		}
		else if(theUploader.imagesArray.length == 1)
		{
			putImageInPreviewer(theUploader.imagesArray[0]);
			enableButtonsWhenNoPictures(deleteButtonEl, deleteImage);
		}
		else
		{
			emptyPreviewer();
			if(noPictureEl)
			{
				putNoPicElInPreviewer(noPictureEl);
			}
			disableButtonsWhenNoPictures(deleteButtonEl);
		}
		showImagesThumbs();
	}

	function afterUploadImage(r){
		var imageReceived = JSON.parse(r);
		createImage(imageReceived);
		var imageCreated = theUploader.imagesArray[theUploader.imagesArray.length - 1];
		debugger;
		insertThumbnail(imageCreated);
		enableButtonsWhenNoPictures(deleteButtonEl, deleteImage);
	}

	function insertThumbnail(imageCreated)
	{
		putImageInPreviewer(imageCreated);
		showImagesThumbs();
	}

	function afterSetImage(r){
		debugger;
		//alert("The picture was set as main picture.");
		for(var i=0; i<theUploader.imagesArray.length; i++)
		{
			theUploader.imagesArray[i].selected = false;
		}
		theUploader.imageInPreviewer.selected = true;
		theUploader.imageSet = theUploader.imageInPreviewer;

	}
	function createImage(imageReceived)
	{
		debugger;
		var url = imageReceived.url;
		var pk = imageReceived.pk;
		var cssClass = imageReceived.cssClass;
		var rawObj = imageReceived;
		var imageCreated = new Image(url, pk, cssClass, rawObj);
		theUploader.imagesArray.push(imageCreated);
		if(imageReceived.selected)
		{
			putImageInPreviewer(imageCreated);
			imageCreated.selected = true;
		}
		return imageCreated;
	}
	function processExantImages(theImages)
	{
		debugger;
		var selectedImage = null;
		for(var i=0; i<theImages.length; i++)
		{
			var imageReceived = theImages[i];
			var createdImage = createImage(imageReceived);
			if(imageReceived.selected)
			{
				selectedImage = createdImage;
			}
		}
		if(selectedImage)
		{
			putImageInPreviewer(selectedImage);
			theUploader.imageSet = selectedImage;
		}
		else
		{
			if(theUploader.imagesArray.length > 0){
				putImageInPreviewer(theUploader.imagesArray[theUploader.imagesArray.length - 1]);
			}
			
		}
		if(!theImages || theImages.length == 0)
		{
			if(noPictureEl)
			{
				putNoPicElInPreviewer(noPictureEl);
			}
			disableButtonsWhenNoPictures(deleteButtonEl);
		}
		else
		{
			enableButtonsWhenNoPictures(deleteButtonEl, deleteImage);
		}
	}
	function init()
	{
		debugger;
		addButtonEl.on("click", uploadImage);
		deleteButtonEl.on("click", deleteImage);
		if(setImageButtonEl)setImageButtonEl.on("click", markImageAsSelected);
		nextBttnEl.on("click", doNext);
		backBttnEl.on("click", doBack);
		processExantImages(theImages);
		showImagesThumbs();

	}


	function uploadImage()
	{
		theForm.empty();
		//var i = document.createElement("input");
		var i =  createElement("input name=\"imageUrl\" type=\"file\" accept=\"image/*\"");
		//var input = $(i);
		//var input = createElement("input name=\"imageUrl\" type=\"file\" accept=\"image/*\" style=\"position: absolute; top: -200px;\"");
		theForm.append(i);
		var onChangeFx = function()
		{
			var ifValidDoUpload = function()
			{
				uploadImageFx(theForm, afterUploadImage);
			};

			var files = this.files;
			var validImage = false;
    		if(files && files[0])
    		{
    			imageValidator(files[0], ifValidDoUpload);
    		}
    		else
    		{
    			alert("No file was found.");
    			return;
    		} 
			
		};
		$(i).on("change", onChangeFx);
		$(i).trigger("click");
	}

	function deleteImage()
	{
		if(confirm("Are you sure you want to remove this image?"))
		{
			deleteImageFx(theUploader.imageInPreviewer, afterDeleteImage);
		}
	}

	this.imageDeleter = deleteImage;

	function markImageAsSelected()
	{
		debugger;
		setImageFx(theUploader.imageInPreviewer, afterSetImage);
	}

	function showImagesThumbs()
	{
		var imagesLeftToShow = numberImagesToShow;
		var doShow = function(startingIndex)
		{
			for(var i = 0; i<startingIndex; i++)
			{
				theUploader.imagesArray[i].imageEl.remove();
			}
			for(var i = startingIndex; i<startingIndex + imagesLeftToShow; i++){
				if(i >= theUploader.imagesArray.length){
					break;
				}
				thumbsContainerEl.append(theUploader.imagesArray[i].imageEl);
			}
		};

		if(theUploader.imagesArray.length > 0){
			var currentDisplayedIndex = theUploader.imageInPreviewer ? theUploader.imagesArray.indexOf(theUploader.imageInPreviewer) : 0;
			if(currentDisplayedIndex == 0)
			{
				var startingIndex = currentDisplayedIndex;
				doShow(startingIndex, imagesLeftToShow);

			}else if(currentDisplayedIndex > 0){
				var startingIndex;
				var stepsBack = imagesLeftToShow - 1;
				while(currentDisplayedIndex > 0 && stepsBack > 0)
				{
					startingIndex = currentDisplayedIndex - 1;
					stepsBack--;
					currentDisplayedIndex--;
				}
				doShow(startingIndex);
			}
		}
	}

	function doNext()
	{
		debugger;
		var currentDisplayedIndex = theUploader.imageInPreviewer ? theUploader.imagesArray.indexOf(theUploader.imageInPreviewer) : 0;
		if(currentDisplayedIndex + 1 < theUploader.imagesArray.length)
		{
			var currentDisplayedElement = theUploader.imagesArray[currentDisplayedIndex].imageEl;
			if(thumbsContainerEl.children().index(currentDisplayedElement) == numberImagesToShow -1){
				thumbsContainerEl.children().first().detach();
			}
			var elementToInsert = theUploader.imagesArray[currentDisplayedIndex + 1].imageEl;
			if(thumbsContainerEl.children().index(elementToInsert) == -1)
			{
				elementToInsert.insertAfter(thumbsContainerEl.children().last());
			}
			putImageInPreviewer(theUploader.imagesArray[currentDisplayedIndex + 1]);

			if(afterNext)
			{
				afterNext();
			}
				
		}
	}

	function doBack()
	{
		debugger;
		var currentDisplayedIndex = theUploader.imageInPreviewer ? theUploader.imagesArray.indexOf(theUploader.imageInPreviewer) : 0;
		if(currentDisplayedIndex > 0)
		{
			var currentDisplayedElement = theUploader.imagesArray[currentDisplayedIndex].imageEl;
			if(thumbsContainerEl.children().index(currentDisplayedElement) == 0 && (numberImagesToShow - 1 > 0))
			{
				thumbsContainerEl.children().last().detach();				
			}
			var elementToInsert = theUploader.imagesArray[currentDisplayedIndex - 1].imageEl;
			if(thumbsContainerEl.children().index(elementToInsert) == -1)
			{
				elementToInsert.insertBefore(thumbsContainerEl.children().first());
			}
			putImageInPreviewer(theUploader.imagesArray[currentDisplayedIndex - 1]);

			if(afterBack)
			{
				afterBack();
			}
		}
	}

	init();
}